'''
Descripttion: 
    针对60 个健康人的运动时序心电数据进行数据预处理。
    数据包括用户基本信息和15个心电数据指标，本次实验主要对15个心电数据指标进行数据预处理。
    流程为：
    （1）数据清洗
        a.去除无用数据列（时间，dO2/dW（全0数据），SpO2（不准确数据））
        b.数据类型转换（object -> float)
        c.缺省值处理 
            重要的特征：HR，能量代谢率与能量消耗，储备心率，呼吸频率，二氧化碳产生量，跑步机速度与坡度
            
version: 
Author: Yang jin
Date: 2020-10-15 10:01:30
LastEditors: Yang jin
'''
#%%
import pandas  as pd
import os
import numpy as np
from scipy.interpolate import splev, splrep
from matplotlib import pyplot as plt
import copy

PATH_BASE = "../data"

#%%
def find_data_files(path_base):
    paths = set()
    for root,dirs,files in  os.walk(path_base):
        for f in files:
            path = os.path.join(root,f)
            if os.path.splitext(path)[1] == '.xlsx' and not path.startswith("~"):
                paths.add(path)
        for d in dirs:
            path = os.path.join(root,d)
            if os.path.splitext(path)[1] == '.xlsx' and not path.startswith("~"):
                paths.add(path)
    return paths

def load_data(path,sheet_name=2,header = None):
    df = pd.read_excel(path,sheet_name,header)
    return df
#%%
paths = list(find_data_files(PATH_BASE))
df = load_data(paths[0],1)
df.columns = ['Time', 'dO2/dW', 'VO2', 'MET', 'EE', 'HR',\
       'Psys', 'EVCO2', 'SpO2', 'Elev', 'Speed', 'VCO2', \
       'HRR', 'BR', 'BF']
#%% 
def delete_useless(dataframe):
    """删除无用数据字段和行,后重建索引
    """
    dataframe.drop([0,1,2],inplace=True) # 删除第0行和第1行注释信息
    
    dataframe.drop(['Time','dO2/dW','SpO2'],axis = 1,inplace=True) # 删除无用和不准确指标
    
    dataframe= dataframe.reset_index(drop=True)
    return dataframe

df = delete_useless(df)
df.dtypes
#%%
def convert_dtypes(dataframe):
    """将数据类型转换为float64和int64
    """
    for col in df.columns: 
        dataframe[col] = pd.to_numeric(dataframe[col],errors="coerce")
    return dataframe

df = convert_dtypes(df)
df.dtypes
#%%
def find_nan(dataframe):
    """查看数据的各属性的缺失比例
    """
    check_null = dataframe.isnull().sum(axis=0).sort_values(ascending=False)/float(len(dataframe)) 
    print(check_null) 

find_nan(df)

#%%
def fill_nan(dataframe):
    """数据类型离散数据和连续数据，采用三种方案填充数据：
    （1）简单直接方法：对数据直接做插值填充;详细地，按照属性的重要程度和缺失比例进行插值填充。
    （3）回归预测的方法：最近邻插值，随机森林回归等，回归预测模型用回归的方法，综合利用其他属性对缺失数值进行预测
    """
    pass

#%%
def fill_nan_interpolation(dataframe,col = ["EVCO2"]):
    """插值方法：(1)邻近点插值，线性插值，多项式插值，
    (2)泰勒插值的两种变体（拉格朗日插值法(n很大，龙格现象)；牛顿插值）；
    (3)分段插值法(在每个区间上，用函数逼近样本点，光滑性差）；
    (4)样条插值法（0-3阶的插值，常用）
    采用一阶样条插值填充缺省值。
    """
    x = np.linspace(1,len(dataframe[col]),len(dataframe[col]))
    y = copy.deepcopy(dataframe[col])
    nan_index = dataframe[col].isnull()
    nan_index = nan_index[nan_index["EVCO2"]==True].index

    if len(nan_index) > 0:
        x_clean = np.delete(x,nan_index)
        y_clean = y.dropna()
        spl = splrep(x_clean,y_clean,k=1)
        new_y = splev(x,spl)
        plt.plot(x_clean,y_clean,'o',x,new_y)
        dataframe[col] = new_y
    
    return dataframe
 
df = fill_nan_interpolation(df)
    

# %%
